#pragma once
#include <cstdint>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/message.h>
#include <google/protobuf/service.h>
#include <google/protobuf/stubs/callback.h>

namespace RPC
{
    // 这是主要用于客户端的
    class MyrpcChannel : public google::protobuf::RpcChannel
    {
        // 这个类是实现RPC远程过程调用的网络通信接口类，通过将网络通信封装在这里面，可以让用户不用知道底层通信，
        // 直接调用远程机器的服务；就像调用自己的本地的方法一样；
    public:
        MyrpcChannel( std::string ip, short port, bool connectNow );
        /**
         * @brief 这是重写的RpcChannel的虚函数，当我们使用stub代理来发起RPC调用时会走这个重写的函数
         *
         * @param method
         * //这是服务中的方法的描述符，这里面封装了服务方法的元数据，描述该方法的相关信息，比如方法名称、输入消息类型、输出消息类型
         * @param controller
         * @param request
         * @param response
         * @param done
         */
        void CallMethod( const google::protobuf::MethodDescriptor *method,
                         google::protobuf::RpcController *controller,
                         const google::protobuf::Message *request,
                         google::protobuf::Message *response,
                         google::protobuf::Closure *done ) override;

    private:
        /**
         * @brief
         *  这个函数是用来完成连接的，如果连接成功，则会返回true；否则返回false，并填充errMsg字段
         * @param ip   //这是ip的引用
         * @param port
         * @param errMsg 成功时返回true，errMsg字段为空字符串；否则为false，填充错误信息
         * @return true
         * @return false
         */
        bool newConnect( const char *ip, uint16_t port, std::string &errMsg );

    private:
        int m_client_fd;
        const std::string m_ip;
        const uint16_t m_port;
    };
}  // namespace RPC
